﻿using System;
using System.Web.Mvc;
using DNT.RavenQA.Core.Extensions;
using DNT.RavenQA.Core.Models;
using DNT.RavenQA.Web.Infrastructure.Commands;
using DNT.RavenQA.Web.Infrastructure.Filters;
using DNT.RavenQA.Web.ViewModels;
using log4net;
using Raven.Abstractions.Exceptions;
using Raven.Client;

namespace DNT.RavenQA.Web.Controllers
{
    public class AnswerController : ContributeController
    {
        public AnswerController(IDocumentSession session, ILog log)
            : base(session, log) { }

        [Authorize]
        [HttpPost]
        [UnitOfWork]
        [ValidateAntiForgeryToken]
        [ValidateInput(false)]
        public ActionResult Add(AnswerInput input, Int32 id)
        {
            input.EnsureIsNotNull("input");

            input.Author = CurrentUser;
            input.Question = DocumentSession.Load<Question>(id);

            if (!ModelState.IsValid)
                return AddFailed(input);

            try { new AddAnswerCommand(input).Execute(DocumentSession); }
            catch (Exception exc)
            {
                Log.Error("An error has occurred while adding a new question.", exc);
                throw;
            }

            return RedirectToAction("Details", "Question", new {id});
        }

        private ActionResult AddFailed(AnswerInput input)
        {
            return null; // TODO: What are you gonna do?
        }

        [UnitOfWork]
        [Authorize]
        public JsonResult Accept(Int32 id)
        {
            Object result;
            DocumentSession.Advanced.UseOptimisticConcurrency = true;

            try
            {
                new AcceptAnswerCommand(new AcceptAnswerCommand.Input
                                                     {
                                                         AnswerId = id,
                                                         User = CurrentUser
                                                     }).Execute(DocumentSession);

                result = new
                {
                    Error = String.Empty,
                    Id = id
                };
            }
            catch (NonExistingContributeException)
            {
                result = new {Error = "Contribute doesn't exist."};
            }
            catch (AnswerAlreadyAcceptedException)
            {
                result = new {Error = "Cannot accept answer twice."};
            }
            catch (ConcurrencyException)
            {
                result = new {Error = "Server error."};
            }

            return Json(result);
        }
    }
}